home *** CD-ROM | disk | FTP | other *** search
- .TITLE KERMIT-65 Hayes micro modem
- .SBTTL 6502 version - Ted Medin
-
- ; Version 1.0
-
- ; Based on the KERMIT Protocol.
-
- ; $Header: apphmm.m65,v 1.8 90/10/15 14:23:32 medin Locked $
- .SBTTL Define start address for assembly
-
- .=$1003 ;[39] Start assembly at hex 1003
-
- .SBTTL Revision History
-
- ;
- ; Edit # Description
- ; ------ -----------
- ;
-
- ;$Log: apphmm.m65,v $
- Revision 1.8 90/10/15 14:23:32 medin
- new org of $7f00 for 3.87
- version 1.8
-
- ;Revision 1.7 88/12/22 09:26:51 medin
- ;use the time constant for the wait routine
-
- ;Revision 1.6 88/02/06 21:41:04 medin
- ; Correct bug in checking status for output ready. Happens only when
- ;host has asked us to stop flow.
- ;Change output routine to check for input ch ready before exiting.
-
- ;Revision 1.5 88/01/15 08:41:26 medin
- ;New origin for 3.81
-
- ;Revision 1.4 87/06/29 10:39:29 medin
- ; Change wait routine to use apple rom wait, change org to work with 3.78.
-
- ;Revision 1.3 87/05/13 18:11:36 medin
- ; Change org to correspond with 3.76
-
- ;Revision 1.2 87/02/21 00:01:58 medin
- ;Put the version in the hearld so we can keep track of the com drivers
- ;also. Thanks Rhoda.
-
- ;DONT FORGET TO UPDATE THE VERSION
- ;Revision 1.1 86/10/28 10:32:10 medin
- ;Initial revision
-
- ;
- ;
- ; Vector for com cards starts here
- ; location $1003 for data
- ; location $1020 for routine jumps
- ; location $1040 for main routines
- ;
- sscdbd: .blkb 1 ;[54]contains baud index(ala super serial card) used by init
- ; 6 - 300 baud
- ; 7 - 600
- ; etc
- .blkb 1 ;
- crdnam: .word herld ;[54] null terminated string of who we are
- kersli: .blkb 1 ;[54] com slot $n0
- kerins: .blkb 1 ;[54] force initialization flag-when 0
- endker: .blkb 2 ;[54] address of end of main kermit
- flowfg: .blkb 1 ;flow control (xon xoff) flag true when hi bit set
- tl0end .word endcom ;[1.5] end of this routine
- timect .blkb 1 ;[1.7] 1 ms of delay via rom wait rtn
- .=sscdbd+29 ;[54] future expansion
- jmp tl2int ;[54] initialize com card
- jmp tl2cmd ;[54] command for ACIA in A
- ;
- ; 0 - hang up
- ; $0b - set baud
- ; $0c - set break on the line
- ; $91 - xon
- ; $93 - xoff
- ;
- ;[54] routine will return false(0) if unable
- jmp tl2cp ;[54] check for input ch ready-0 false
- jmp tl2gpc ;[54] get input ch
- jmp tl2ppc ;[54] put output character
- jmp tl2exi ;[54] reset card and restore initialized
- .=sscdbd+29+32 ;[54] futures
- ;[1.4]wait: .blkb 3 ;[54] wait routine-a reg contains milliseconds
- wait: .blkb 3 ;[1.4] apple rom wait rtn 220=125ms,206=108ms,25=2ms
- prstr: .blkb 3 ;[54] print string-x=lsb,y=msb of null terminated string
- urdkey: .blkb 3 ;[54] read keyboard
- prcrlf: .blkb 3 ;[54] print cr and lf
- telcnc .blkb 3 ;check for keyboard character
- telspa .blkb 3 ;set character parity
-
- ;[1.4] .=$7200 ;[54] place to start com card assembly
- .=$7f00 ;[1.8][1.5] place to start com card assembly
- start = . ;need a label at begining
- kr0pch = $c087 ;[12] Base for port char location (DC Hayes)
- kr0pst = $c086 ;[12] Base for port strobe locations (DC Hayes)
- kr0pcr = $c086 ;[41] Base for prot control register (DC Hayes)
- kr0pcc = $c085 ;[48] Modem control port
- kbd = $c000 ; Keyboard character input location
- cr = $d ; <cr>
- apinc1 = 3 ;[48] first init char for 6850 acia
- apinc2 = $11 ;[48] second init (8-bits)
- hctrlq = $91 ;^Q with high bit set
- hctrls = $93 ;^S "
- hctrlz = $9a ;^Z "
- ctrlq = $11 ;[59] ^Q
- ctrls = $13 ;[59] ^S
- setio2 = $fe93 ; place for pr#0
- cswl = $36
- cswh = $37
- rdkey = $fd0c ; read a ch from current input device
- cout = $fded ; print a ch to current output device
- kwrk01 .byte ;[1.7]
- temp .byte ;[48] work space for dial
- pinptr .byte ; input buffer pointer
- inptr .byte ; input buffer pointer for get
- poutpt .byte ;[59] output buffer pointer
- outptr .byte ;[59] " " " for put
- ksli .byte ; com slot $0n
- dch.cr = $7f8 ;[41] Save area for Control register
- herld nasc <HAYES MICRO MODEM V1.8> 1 ;tell who we are
- bad nasc <COM ROUTINES ASM TOO LOW IN MEMORY> 1
- dialms: nasc <NUMBER TO DIAL:> 1 ;[48]
- dialm2: nasc <AWAITING CARRIER...ANY KEY ABORTS> 1 ;[48]
- dialm3: nasc <CONNECTED.> 1 ;[48]
- dialm4 nasc <THERE WILL BE A 35 SEC DELAY> 1
-
-
- ;
- ; D. C. Hayes I/O Device support - These routines support the
- ; D. C. Hayes Micromodem.
- ;
-
-
- tlini9: lda #1 ;[59] give true return
- rts ;[48] only way to reach this
-
- tl2int:
- lda #start^
- cmp endker+1 ;are we loaded above main
- beq dontno ;cant tell yet
- bcc trble ;yes we are in trouble
- bcs setnm ;ok
- dontno lda #start\ ;well lets check 16 bits
- cmp endker
- beq setnm ;whee just exactly right
- bcs setnm ;ok
- trble ldx #bad\ ;got to tell someone
- ldy #bad^
- jsr prstr ;print the message
- jsr prcrlf ;and terminate it properly
- setnm:
- init0:
-
- tlinit: ;[48]
- ldx kersli ;[48] get device slot
- lda kr0pch,x ;[48] access data
- lda kr0pst,x ;[48] now for the status
- and #4 ;[48] do we have a carrier?
- beq tlini9 ;[48] yes,carry on
- txa ; calculate $0n from $n0
- lsr a
- lsr a
- lsr a
- lsr a
- sta ksli ; now we have $0slot
- ldx #dialm4\ ; tell about the delay
- ldy #dialm4^
- jsr prstr
- jsr prcrlf ;and make it look nice
- lda cswl ; save output hooks
- pha
- lda cswh
- pha
- lda ksli ; now make it pr#slot
- jsr setio2+2
- lda #hctrlq ; ^q starts dialing
- jsr cout
- lda #cr+$80 ; ^m end of dialing wait for carrier
- jsr cout
- lda #hctrlz ; ^z hang up
- jsr cout
- ;[1.4] lda #10
- lda #20 ;[1.4]
- sta temp ; wait for 2.5 sec, slow phone co
- ;[1.4]tlini0 lda #250
- ;[1.4] jsr wait ; .250 sec at a time
- ;[1.7]tlini0 lda #220 ;[1.4] 125 ms
- tlini0 lda #125 ;[1.7] 125 ms
- sta kwrk01 ;[1.7]
- tlinii lda timect ;[1.7] 1 ms at a time
- jsr wait ;[1.4]
- dec kwrk01 ;[1.7]
- bne tlinii ;[1.7]
- dec temp
- bne tlini0
- pla ; we are now thru so restore output
- sta cswh
- pla
- sta cswl
- lda #$8d ;[48] go offhook to dial
- ldx kersli ;[48] get slot again and again and again ...
- sta kr0pcc,x ;[48]
- lda #apinc1 ;[48] init acia ch 1
- sta kr0pch,x ;[48]
- lda #apinc2 ;[48] init acia ch 2
- sta kr0pch,x ;[48]
- ;[1.4] lda #10 ;[48] now to wait 2.5 sec
- lda #20 ;[1.4] now to wait 2.5 sec 125ms at a time
- sta temp ;[48]
- ;[1.4]tlini2: lda #250 ;[48] 250 ms.
- ;[1.7]tlini2: lda #220 ;[1.4] 125 ms.
- tlini2: lda #125 ;[1.7] 125 ms.
- ;[1.4] jsr wait ;[48] there goes x again
- sta kwrk01 ;[1.7] 1 ms at a time
- tlinih lda timect ;[1.7]
- jsr wait ;[1.4]
- dec kwrk01 ;[1.7]
- bne tlinih ;[1.7]
- dec temp ;[48]
- bne tlini2 ;[48] all 2.5 sec? no
- ldx #dialms\ ;[48] now for the dial message
- ldy #dialms^ ;[48]
- jsr prstr ;[48] print it
- tlini5: jsr rdkey ;[48] get a ch from keyboard
- jsr cout ; and print it
- and #$7f ;[48] drop high bit
- cmp #'0 ;[48] you can never tell what one types
- bmi notnum ;[48] its not in the number range fro ascii
- cmp #$3a ;[48] well it may be a number
- bpl notnum ;[48] no, its too big
- and #$f ;[48] get the digits
- bne tlini3 ;[48] is it a zero
- lda #10 ;[48] yes, thats 10 pulses
- tlini3: sta temp ;[48] thats the count of pulses
- tlini4: lda #$d ;[48] go on hook
- ldx kersli ;[48] the slot again
- sta kr0pcc,x ;[48] tell the chip
- ;[1.4] lda #61 ;[48] this is a 61 ms delay
- ;[1.7] lda #154 ;[1.4] this is a 61 ms delay
- lda #61 ;[1.7] this is a 61 ms delay
- sta kwrk01 ;[1.7]
- tlinib lda timect ;[1.7] 1 ms at a time
- jsr wait ;[48]
- dec kwrk01 ;[1.7]
- bne tlinib ;[1.7]
- lda #$8d ;[48] off hook
- ldx kersli ;[48] you know what this is by now
- sta kr0pcc,x ;[48] tell
- ;[1.4] lda #39 ;[48] now for a 39 ms delay
- ;[1.7] lda #123 ;[1.4] now for a 39 ms delay
- lda #39 ;[1.7] now for a 39 ms delay
- sta kwrk01 ;[1.7]
- tlinif lda timect ;[1.7] 1 ms at a time
- jsr wait ;[48]
- dec kwrk01 ;[1.7]
- bne tlinif ;[1.7]
- dec temp ;[48] all the pulses ?
- bne tlini4 ;[48] no, keep on
- ;[1.4] lda #3 ;[48] wait for 600 ms
- lda #6 ;[1.4] wait for 600 ms
- sta temp ;[48]
- ;[1.4]tlini6: lda #200 ;[48]
- ;[1.7]tlini6: lda #198 ;[48] 100ms
- tlini6: lda #100 ;[1.7] 100ms
- sta kwrk01 ;[1.7]
- tlinig lda timect ;[1.7] 1 ms at a tiime
- jsr wait ;[48]
- dec kwrk01 ;[1.7]
- bne tlinig ;[1.7]
- dec temp ;[48]
- bne tlini6 ;[48]
- jmp tlini5 ;[48] get the next number
- notnum: cmp #cr ;[48] is this the end
- bne tlini5 ;[48] nope try for a number
- jsr prcrlf ;[48] make the screen look nice
- ldx #dialm2\ ;[48] now for the waiting msg
- ldy #dialm2^ ;[48]
- jsr prstr ;[48] print it
- ldx kersli ;[48] the slot again
- tlini8: bit kbd ;[48] do we have a ch from the keyboard
- bpl tlini7 ;[48] no, try for carrier
- jsr rdkey ; lets do this right
- lda #0 ;[48]
- ldx kersli ;[48] the slot again
- sta kr0pcc,x ;[48] hang up and give up
- lda #0 ; give a false return (0)
- rts ;[48]give a false return (0)
- tlini7: lda kr0pch,x ;[48] the data
- lda kr0pst,x ;[48] and now the status
- and #4 ;[48] carrier?
- bne tlini8 ;[48] not yet try again
- lda #$8f ;[48] originate mode+ap300+apoffh
- sta kr0pcc,x ;[48] tell
- jsr prcrlf ;[48]
- ldx #dialm3\ ;[48] tell we got carrier
- ldy #dialm3^ ;[48]
- jsr prstr ;[48]
- jsr prcrlf ;[48]
- lda #0 ;start the buffer at 0
- sta pinptr
- sta inptr
- sta poutpt ;[59] "
- sta outptr ;[59] "
- lda #1 ; give a true return (non 0)
- rts ;[48] finally
-
- tl2cp:
- ldx kersli ;[12] Offset into I/O locations
- tl0cp1: lda kr0pst,x ;[12] Try for a character
- and #$01 ;[12] Check for receive register full
- beq tl0cp7
- lda kr0pch,x ; get ch
- ldy pinptr ; get place to store
- sta inbuf,y ; in buf
- inc pinptr ; ready for next
- bit flowfg ;[59] how about flow control
- bpl tl0cp7 ;[59] no
- lda inbuf,y ;[59] get input ch
- and #$7f ;[59] drop parity etc
- ; bvc tl2cp4 ;[59] yes,how about ^S received?, no
- cmp #ctrlq ;[59] is this continue(start up outputing)
- bne tl2cp4 ;[59] no, check for ^S
- lda flowfg ;[59] tattle about the continue
- and #$bf ;[59]
- sta flowfg ;[59]
- dec pinptr ;[59] forget about this character
- tl2cp2 ldy outptr ;[59] see if any to output
- cpy poutpt ;[59] well?
- beq tl0cp7 ;[59] no more we have put all
- tl2cp3 lda kr0pst,x ;[59] check status for output
- ;[1.6] and #$10 ;[59] ready?
- and #2 ;[1.6] ready?
- beq tl2cp3 ;[59] no, spin
- lda outbuf,y ;[59] output ch
- sta kr0pch,x ;[59] bye
- inc outptr ;[59] ready for next
- jmp tl2cp2 ;[59]
- tl2cp4 cmp #ctrls ;[59] is this stop?
- bne tl0cp7 ;[59] no
- lda #$40 ;[59] yes, tattle
- ora flowfg ;[59]
- sta flowfg ;[59] now everyone knows
- dec pinptr ;[59] forget about the ^S character
- tl0cp7:
- lda pinptr
- cmp inptr
- ;[12] No character, return false(zero)
- ;[12] Successful return, return true(non 0)
- rts ;[12] ...
-
- tl2gpc:
- ldx inptr ;get where the ch is
- lda inbuf,x ;get ch
- inc inptr
- tl0rtc: rts ;[12] and return
-
- tl2ppc:
- pha ;[12] Hold the byte to send
- ldx kersli ;[12] Get I/O location offset
- tl0pp1: lda kr0pst,x ;[12] Get the status byte
- and #$02 ;[12] Isolate the flag we want (TRE)
- beq tl0pp2 ;[12] Transmit register is NOT empty, try again
- bit flowfg ;[59] flow control?
- bpl tl2pp0 ;[59] no
- bvc tl2pp0 ;[59] should we stop outputing?,no
- ldy poutpt ;[59] yes, save this ch in buffer
- pla ;[59]
- sta outbuf,y ;[59]
- inc poutpt ;[59] tell how many
- ;[1.6] rts ;[59] thats all
- jmp tl0cp1 ;[1.6] check for input and return
- tl2pp0 ;[59]
- pla ;[12] Fetch the data byte off the stack
- sta kr0pch,x ;[12] Stuff it at the proper loc to send it
- ;[1.6] rts ;[59] thats all
- jmp tl0cp1 ;[1.6] check for input and return
-
- tl0pp2: jsr tl0cp1 ;go check for an input ch
- jmp tl0pp1 ;try output again
-
- tl2exi:
- lda #0 ;tell we did this
- ldx kersli ;[47] get slot number
- sta kr0pcc,x ;shut it down
- exit9: rts
-
- tl2cmd: ;find out what command
- beq tl0drp ;its drop line
- cmp #$0c
- beq break ;its a break command
- cmp #$0b
- beq tl2rts ;its a set baud command and we cant
- cmp #hctrlq
- beq tl2sac ;its a xon command
- cmp #hctrls
- beq tl2sac ;its a xoff command
- tl2fls: lda #0 ;unknown command
- tl2rts: rts ;que passo ? return false(0)
- tl2sac: ldx flowfg ;do we have flow control
- bpl tl2fls ;no return false
- and #$7f ;drop high bit
- jsr telspa ;set parity
- jsr tl2ppc ;output the ch
- lda #1 ;return a true
- rts
- tl0drp:
- ldx kersli ;[47] get slot number
- sta kr0pcc,x ;shut it down
- lda #1 ;[54] true return
- rts
- break:
- ldy kersli ;[41] Get slot index,form = $n0
- ldx ksli ; and $0n where n = slot
- lda dch.cr,x ;[41] Get saved Control Register
- ora #$60 ;[41] Set appropriate flags for break
- sta kr0pcr,y ;[41] Start break signal
- ;[1.4] lda #233 ;[41] Wait for 233 ms.
- ;[1.4] jsr wait ;[41] Do it, say goodby to x
- ;[1.7] lda #220 ;[1.4] Wait for 125 ms.
- lda #233 ;[1.7] Wait for 233 ms.
- sta kwrk01 ;[1.7]
- break3 lda timect ;[1.7] 1 ms at a time
- jsr wait ;[1.4]
- dec kwrk01 ;[1.7]
- bne break3 ;[1.7]
- ;[1.7] lda #206 ;[1.4] Wait for 108 ms a total of 233ms.
- ;[1.7] jsr wait ;[1.4]
- ;[1.7] ldx ksli ; restore x
- lda dch.cr,x ;[41] Get saved Control reg
- and #$9f ;[41] Reset flags
- ;[1.7] ldy kersli ;[41] Get slot index
- sta kr0pcr,y ;[41] Stop break signal
- rts ;[41] and return
- inbuf .blkb 256 ;input buffer
- outbuf .blkb 256 ;[59] output "
- endcom ;[1.5]
-